package com.winit.openapi.util;

import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
import org.apache.pdfbox.exceptions.COSVisitorException;
import org.apache.pdfbox.util.PDFMergerUtility;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import sun.misc.BASE64Encoder;

import com.winit.openapi.exception.ApiException;

/**
 * 获取PDF文件,将PDF文件合并.
 * 
 * @version <pre>
 * Author	Version		Date		Changes
 * liang.lu 	1.0  		Mar 17, 2015 	Created
 * 
 * </pre>
 * @since 1.
 */
public class PDFBox4MergePDF {

    /**
     * 
     */
    Logger logger = LoggerFactory.getLogger(PDFBox4MergePDF.class);

    public static void main(String[] args) {
       PDFBox4MergePDF tool = new PDFBox4MergePDF();
        try {
            List<String> pdfs = new ArrayList<String>();
            String url1 = "http://172.16.2.63/label/2015/03/12/IC2492341450903667CN_999999.PDF";
            String url2 = "http://172.16.2.63/label/2015/03/13/IC2492347850903667CN_999999.PDF";
            pdfs.add(url1);
            pdfs.add(url2);
            String name = "F://src//Winit//2015//03//tmp//tmp.pdf";
            File file = new File(name);
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }
            tool.merge(pdfs, name);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 合并文件
     * 
     * @param failePath 需要合并的文件列表
     * @param outputFilePath 合并输出文件路径
     */
    public void merge(List<String> urls, String outputFilePath) throws IOException {

        File file = new File(outputFilePath);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        OutputStream outputStream = new FileOutputStream(outputFilePath);
        PDFMergerUtility merger = new PDFMergerUtility();
        merger.setDestinationStream(outputStream);
        InputStream inputStream = null;
        for (String url : urls) {
            logger.info("PDFBox4MergePDF->merge url:{}", url);
            try {
                inputStream = this.getStreamByUrl(url);
                if (null != inputStream) {
                    merger.addSource(inputStream);
                }
            } catch (Exception e) {
                logger.error("PDFBox4MergePDF->merge : exception:{}", e.getLocalizedMessage());
            }
        }
        try {
            merger.mergeDocuments();
        } catch (COSVisitorException e) {
            logger.error("PDFBox4MergePDF->merge : exception:{}", e.getLocalizedMessage());
        } finally {
            outputStream.close();
            if (null != inputStream) {
                inputStream.close();
            }
        }
    }

    /**
     * 合并文件
     * 
     * @param failePath 需要合并的文件列表
     * @param outputFilePath 合并输出文件路径
     * @param count 合并打印份数
     */
    public void merge(List<String> urls, String outputFilePath, int count) throws IOException {
        List<String> newUrls = new ArrayList<String>();
        for (String string : urls) {
            for (int i = 0; i < count; i++) {
                newUrls.add(string);
            }
        }
        merge(newUrls, outputFilePath);
    }

    /**
     * 根据文件的URL获取文件流
     * 
     * @param urlStr
     * @return
     */
    private InputStream getStreamByUrl(String urlStr) {

        URL url = null;
        logger.info("MergePDF->getStreamByUrl url:{}", urlStr);
        try {
            url = new URL(urlStr);
        } catch (MalformedURLException me) {
            me.printStackTrace();
            return null;
        }
        HttpURLConnection conn = null;
        InputStream inputStream = null;
        try {
            conn = (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(20 * 1000);
            conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
            inputStream = conn.getInputStream();
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            IOUtils.copy(inputStream, outputStream);

            return new ByteArrayInputStream(outputStream.toByteArray());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (null != inputStream) {
                IOUtils.closeQuietly(inputStream);
            }
        }
        return null;
    }

    /**
     * 将文件转成Base64 编码
     * 
     * @param path
     * @return
     */
    public String file2Base64(String path) {

        BASE64Encoder encoder = new BASE64Encoder();
        InputStream inpuSttream = null;
        try {
            inpuSttream = new FileInputStream(path);
        } catch (FileNotFoundException e) {
            logger.info("toBase64:error:{}", e.getLocalizedMessage());
        }
        byte[] byteArray = null;
        try {
            byteArray = IOUtils.toByteArray(inpuSttream);
        } catch (IOException e) {
            logger.info("toBase64:error:{}", e.getLocalizedMessage());
        } finally {
            if (inpuSttream != null) {
                try {
                    inpuSttream.close();
                } catch (IOException e) {
                    logger.info("toBase64:error:{}", e.getLocalizedMessage());
                }
            }
        }
        if (null != byteArray) {
            return encoder.encode(byteArray);
        } else {
            return null;
        }
    }

    /**
     * 删除文件
     * 
     * @param filePath
     * @return
     */
    public Boolean delFile(String filePath) {
        File file = new File(filePath);
        boolean result = false;
        if (file.exists()) {
            result = file.delete();
        }
        return result;
    }

    /**
     * 合并文件
     * 
     * @param bytes List
     * @param out
     * @throws IOException
     */
    public void merge(List<byte[]> bytes, ByteArrayOutputStream out) throws IOException {
        PDFMergerUtility merger = new PDFMergerUtility();
        merger.setDestinationStream(out);
        InputStream inputStream = null;
        for (int i = 0; i <= bytes.size(); i++) {
            try {
                inputStream = new ByteArrayInputStream(bytes.get(i));
                merger.addSource(inputStream);
            } catch (Exception e) {
                logger.error("PDFBox4MergePDF->merge : exception:{}", e.getLocalizedMessage());
            }
        }
        try {
            merger.mergeDocuments();
        } catch (COSVisitorException e) {
            logger.error("PDFBox4MergePDF->merge : exception:{}", e.getLocalizedMessage());
        } finally {
            if (null != inputStream) {
                inputStream.close();
            }
            out.close();
        }
    }
    /**
     * 对象转数组
     * 
     * @param obj
     * @return
     */
    public List<byte[]> decryptBASE64(List<String> obj) {
        if(obj==null || obj.size()<=0){
            return null;
        }
        List<byte[]> list = new ArrayList<byte[]>();
        for (int i = 0; i < obj.size(); i++) {
            list.add(Base64.decodeBase64(obj.get(i)));
        }
        return list;
    }
    /** 
     * 根据byte数组，生成文件 
     */  
    public static void getFile(byte[] bfile, String filePath,String fileName) {  
        BufferedOutputStream bos = null;  
        FileOutputStream fos = null;  
        File file = null;  
        try {  
            File dir = new File(filePath);  
            if(!dir.exists()&&dir.isDirectory()){//判断文件目录是否存在  
                dir.mkdirs();  
            }  
            file = new File(filePath+"\\"+fileName);  
            fos = new FileOutputStream(file);  
            bos = new BufferedOutputStream(fos);  
            bos.write(bfile);  
        } catch (Exception e) {  
            e.printStackTrace();  
        } finally {  
            if (bos != null) {  
                try {  
                    bos.close();  
                } catch (IOException e1) {  
                    e1.printStackTrace();  
                }  
            }  
            if (fos != null) {  
                try {  
                    fos.close();  
                } catch (IOException e1) {  
                    e1.printStackTrace();  
                }  
            }  
        }  
    }  
    /**
     * base 64 encode
     * 
     * @param bytes 待编码的byte[]
     * @return 编码后的base 64 code
     */
    public  String base64Encode(byte[] bytes) {
        String string = null;
        if(bytes==null || bytes.length<=0){
         return  string;  
        }
        try {
            string = new String(Base64.encodeBase64(bytes), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw new ApiException("base64加密失败" + e);
        }
        return string;
    }
}
